%% Wrapper for boxed (and struct) types
classdef GBoxed < glib.GThing

  properties
    class = glib.GInterface.NULL
  end

  methods
    function varargout = subsref(obj, S, noutrequested)
      if nargin < 3
        noutrequested = nargout;
        indirectReturn = false;
      else
        if nargout > 1, error 'Too many outputs for indirect return', end
        indirectReturn = true;
      end
      if length(S) > 2, error 'Too many subscripts for GBoxed', end
      if ~strcmp(S(1).type, '.'), error 'Unsupported subscript', end
      name = S(1).subs;
      if length(S) == 1   % First look for property
        if noutrequested > 1, error 'Too many outputs for GBoxed method', end
        ret = subsref(obj.class, S);
        if indirectReturn, varargout{1} = { ret };
        else varargout{1} = ret; end
      else  % Call the method
        S(2).subs = { obj S(2).subs{:} };
        ret = subsref(obj.class, S, noutrequested);
        if indirectReturn, varargout{1} = ret;
        else varargout = ret; end
      end % only 1 subscript?
    end % function subsref
  
    function s = char(obj)
      if obj.gtype == 0
        s = sprintf('[Struct %s at 0x%lx]', name(obj.class), uint64(obj.value));
      else
        s = sprintf('[Boxed %s at 0x%lx]', name(obj.class), uint64(obj.value));
      end
    end

    %% This is an internal constructor!
    function obj = GBoxed(gtype, value, cls)
      obj@glib.GThing(gtype, value);
      obj.class = cls;
    end
                  
    function delete(obj)
      glib.g_boxed_free(obj.gtype, obj.value);
    end

    function ret = eq(a,b)
      if isa(b, 'glib.GBoxed')
        ret = (a.gtype == b.gtype && a.value == b.value);
      else ret = false; end
    end
    
    function ret = ne(a,b)
      if isa(b, 'glib.GBoxed')
        ret = (a.gtype ~= b.gtype || a.value ~= b.value);
      else ret = true; end
    end

  end  % Public Methods

end  % Classdef
